package be.groept.ace.cursusplanning.model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import be.groept.ace.cursusplanning.persistency.IPersistentieController;
import be.groept.ace.cursusplanning.persistency.IPersistentieProvider;
import be.groept.ace.cursusplanning.persistency.Persisteerbaar;

/**
 * 
 * @author Karim
 *
 */
public class Cursus implements Comparable<Cursus>, Persisteerbaar {
	public final static int MIN_STUDIEPUNTEN = 3;
	public final static int MAX_STUDIEPUNTEN = 6;
	public final static int MIN_LESTIJD = 120;
	public final static int MAX_LESTIJD = 240;
	
	private int cursusCode;
	private String cursusNaam;
	private int studiePunten;
	private int lestijdPerWeek;
	private Opleiding opleiding;
	private Map<String, Lector> lectors;
	private Map<Integer, Cursus> voorgaandeCursussen;
	private List<AangebodenCursus> aangebodenCursussen;
	
	private IPersistentieProvider pProvider;
	
	public Cursus(Integer cursusCode, String cursusNaam, Integer studiePunten, Integer lestijdPerWeek, Opleiding opleiding) throws IllegalArgumentException{
		setCursusCode(cursusCode);
		setCursusNaam(cursusNaam);
		setStudiePunten(studiePunten);
		setLestijdPerWeek(lestijdPerWeek);
		setOpleiding(opleiding);
		lectors = new HashMap<String, Lector>();
		voorgaandeCursussen = new HashMap<Integer, Cursus>();
		aangebodenCursussen = new ArrayList<AangebodenCursus>();
	}
	
	/**
	 * geeft Cursus code terug
	 * @return (int)cursus code 
	 */
	public int getCursusCode() {
		return cursusCode;
	}


	private void setCursusCode(int cursusCode) {
		this.cursusCode = cursusCode;
	}


	/**
	 * geeft cursus naam terug
	 * @return (String) cursusnaam
	 */
	public String getCursusNaam() {
		return cursusNaam;
	}


	private void setCursusNaam(String cursusNaam) throws IllegalArgumentException{
		if(cursusNaam == null || "".equals(cursusNaam)) throw new IllegalArgumentException("Cursus naam mag niet leeg zijn.");
		this.cursusNaam = cursusNaam;
	}


	/**
	 * geeft studiepunten terug
	 * @return (int) studiepunten
	 */
	public int getStudiePunten() {
		return studiePunten;
	}


	private void setStudiePunten(int studiePunten) throws IllegalArgumentException{
		if (studiePunten != MIN_STUDIEPUNTEN && studiePunten != MAX_STUDIEPUNTEN) throw new IllegalArgumentException("Studiepunten moeten ofwel " + MIN_STUDIEPUNTEN + " of " + MAX_STUDIEPUNTEN + " zijn.");
		this.studiePunten = studiePunten;
	}


	/**
	 * geeft lestijd per week terug
	 * @return (int) lestijd per week (is MIN_LESTIJD of MAX_LESTIJD)
	 */
	public int getLestijdPerWeek() {
		return lestijdPerWeek;
	}


	private void setLestijdPerWeek(int lestijdPerWeek) throws IllegalArgumentException{
		if(lestijdPerWeek != MIN_LESTIJD && lestijdPerWeek != MAX_LESTIJD) 
			throw new IllegalArgumentException("Lestijd per week moet " + MIN_LESTIJD + " of "+ MAX_LESTIJD + " uren bedragen.");
		this.lestijdPerWeek = lestijdPerWeek;
	}

	/**
	 * geeft opleiding terug 
	 * @return (Opleiding) opleiding
	 */
	public Opleiding getOpleiding() {
		return opleiding;
	}


	private void setOpleiding(Opleiding opleiding) throws IllegalArgumentException{
		if (opleiding == null) throw new IllegalArgumentException("Opleiding mag niet null zijn.");
		this.opleiding = opleiding;
	}


	/**
	 * geeft de lectors terug
	 * @return (Map<String, Lector) lectors
	 */
	public Map<String, Lector> getLectors() {
		return lectors;
	}
	
	public void addLector(Lector lector) throws IllegalArgumentException {
		if(lector == null) throw new IllegalArgumentException("Lector mag niet null zijn.");
		if(lectors.containsKey(lector.getLectorCode())) throw new IllegalArgumentException("De lector is al geassigneerd voor deze cursus.");
		lectors.put(lector.getLectorCode(), lector);
	}
	
	/**
	 * Geeft alle voorgaande cursussen
	 * @return
	 */
	public Map<Integer, Cursus> getVoorgaandeCursussen() {
		return voorgaandeCursussen;
	}
	
	/**
	 * voegt een voorgaande cursus toe
	 * @param Cursus cursus
	 */
	public void addVoorgaandeCursussen(Cursus cursus) throws IllegalArgumentException{
		if(cursus == null) throw new IllegalArgumentException("cursus mag niet null zijn");
		if(voorgaandeCursussen.containsKey(cursus.getCursusCode())) throw new IllegalArgumentException("De cursus " + cursus.getCursusNaam() + " is al toegevoegd aan deze cursus als voorgaande cursus.");
		voorgaandeCursussen.put(new Integer(cursus.getCursusCode()), cursus);
	}

	/**
	 * Geeft alle aangeboden cursussen.
	 * @return
	 */
	public List<AangebodenCursus> getAangebodenCursussen() {
		return aangebodenCursussen;
	}
	
	/**
	 * Voegt een aangeboden cursus toe voor de cursus
	 * @param aangebodenCursus
	 */
	public void addAangebodenCursus(AangebodenCursus aangebodenCursus) {
		if (aangebodenCursus == null) throw new IllegalArgumentException("Aangeboden cursus mag niet null zijn.");
		if (aangebodenCursussen.contains(aangebodenCursus)) throw new IllegalArgumentException("De aangeboden cursus bestaat al");
		this.aangebodenCursussen.add(aangebodenCursus);
	}

	/**
	 * Vergelijken op code
	 */
	@Override
	public int compareTo(Cursus cursus) {
		return getCursusCode() - cursus.getCursusCode();
	}
	
	@Override
	public String toString() {
		return getCursusNaam();
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + cursusCode;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Cursus other = (Cursus) obj;
		if (cursusCode != other.cursusCode)
			return false;
		return true;
	}

	@Override
	public Object[] getInfoToBeSaved(IPersistentieController pController) {
		return pProvider.getInfoToBeSaved(pController);

	}
	public IPersistentieProvider getPersistentieProvider(){
		return pProvider;
	}
	public void setPersistentieProvider(IPersistentieProvider provider){
		this.pProvider = provider;
	}

	
}
